package com.budwk.app.sqfwV2.component.povertyMonitoring;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.StrFormatter;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.services.SqfwFamilyPropertyService;
import com.budwk.app.sqfw.services.SqfwHouseholdRegistrationInfoService;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.CommonParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.ExcelGenerateParam;
import com.budwk.app.sqfwV2.dto.entity.SqfwFamilyProperty;
import com.budwk.app.sqfwV2.dto.entity.SqfwHouseholdRegistrationInfo;
import com.budwk.app.sqfwV2.dto.povertyMonitoring.FamilyPropertyParamDataDTO;
import com.budwk.app.sqfwV2.dto.povertyMonitoring.QuarterStatisticalTableExcelDTO;
import com.budwk.app.util.adminUtils.CommonCheckUtils;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.spire.ms.System.Collections.Specialized.CollectionsUtil;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author ZY.Wang
 * @since 2024/6/17
 */
public class QuarterStatisticComponent {

    /**
     * 组装统计表excel数据
     *
     * @return 结果
     */
    public static QuarterStatisticalTableExcelDTO createQuarterStatisticalTableExcelData(ExcelGenerateParam excelGenerateParam) {

        String year = (String) excelGenerateParam.getCustomerParamMap().get("year");
        String quarter = (String) excelGenerateParam.getCustomerParamMap().get("quarter");
        String clientType = (String) excelGenerateParam.getClientType();
        CommonParam downloadUserParam = excelGenerateParam.getDownloadUserParam();

        String province = downloadUserParam.getProvince();
        String city = downloadUserParam.getCity();
        String county = downloadUserParam.getCounty();
        String district = downloadUserParam.getDistrict();
        String community = downloadUserParam.getCommunity();

        SqfwFamilyPropertyService sqfwFamilyPropertyService = NutzIocUtils.getBean(SqfwFamilyPropertyService.class);
        SqfwHouseholdRegistrationInfoService sqfwHouseholdRegistrationInfoService = NutzIocUtils.getBean(SqfwHouseholdRegistrationInfoService.class);

        QuarterStatisticalTableExcelDTO result = new QuarterStatisticalTableExcelDTO();
        result.setQuarter(Integer.parseInt(quarter));
        result.setYear(Integer.parseInt(year));
        result.setLastYear(Integer.parseInt(year) - 1);
        result.setQuarterC(StrFormatter.format("{}季度", quarterChinese(Integer.parseInt(quarter))));
        result.setRowDataList(Lists.newArrayList());

        List<QuarterStatisticalTableExcelDTO.QuarterStatisticalTableExcelRowDataDTO> rowDataList = Lists.newArrayList();

        //
        Cnd householdRegistrationCnd = Cnd.NEW();
        if ("web".equals(clientType)) {
            CommonCheckUtils.checkAreaRangeCnd(householdRegistrationCnd);
        } else {
            householdRegistrationCnd.and(SqfwHouseholdRegistrationInfo::getProvince, "=", province)
                    .and(SqfwHouseholdRegistrationInfo::getCity, "=", city)
                    .and(SqfwHouseholdRegistrationInfo::getCounty, "=", county)
                    .and(SqfwHouseholdRegistrationInfo::getDistrict, "=", district)
                    .and(SqfwHouseholdRegistrationInfo::getCommunity, "=", community);
        }
        List<SqfwHouseholdRegistrationInfo> householdRegistrationInfoList = sqfwHouseholdRegistrationInfoService.query(householdRegistrationCnd);
        List<String> householdIdList = householdRegistrationInfoList.stream().map(SqfwHouseholdRegistrationInfo::getId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(householdIdList)) return result;

        // 首先查询出这个季度的家庭数据
        Cnd cnd = Cnd.NEW().and(SqfwFamilyProperty::getYear, "=", year).and(SqfwFamilyProperty::getQuarter, "=", quarter)
                .and(SqfwFamilyProperty::getHouseholdId, "in", householdIdList);
        List<SqfwFamilyProperty> familyPropertyList = sqfwFamilyPropertyService.query(cnd);


        // 需要查询上一年这个季度的家庭数据
        Map<String, SqfwFamilyProperty> lastYearFamilyPropertyMap = Maps.newHashMap();
        Map<String, SqfwFamilyProperty> lastYearFourQuarterPropertyMap = Maps.newHashMap();

        int lastYear = Integer.parseInt(year) - 1;
        Cnd lastYearCnd = Cnd.NEW().and(SqfwFamilyProperty::getYear, "=", lastYear).and(SqfwFamilyProperty::getQuarter, "=", quarter);
        List<SqfwFamilyProperty> lastYearFamilyPropertyList = sqfwFamilyPropertyService.query(lastYearCnd);
        for (SqfwFamilyProperty lastFamilyProperty : lastYearFamilyPropertyList) {
            lastYearFamilyPropertyMap.put(lastFamilyProperty.getHouseholdId(), lastFamilyProperty);
        }

        Cnd lastYearFourCnd = Cnd.NEW().and(SqfwFamilyProperty::getYear, "=", lastYear).and(SqfwFamilyProperty::getQuarter, "=", "4");
        List<SqfwFamilyProperty> lastYearFourQuarterFamilyPropertyList = sqfwFamilyPropertyService.query(lastYearFourCnd);
        for (SqfwFamilyProperty lastYearFourQuarterProperty : lastYearFourQuarterFamilyPropertyList) {
            lastYearFourQuarterPropertyMap.put(lastYearFourQuarterProperty.getHouseholdId(), lastYearFourQuarterProperty);
        }

        for (SqfwFamilyProperty sqfwFamilyProperty : familyPropertyList) {
            String paramDataStr = sqfwFamilyProperty.getParamData();
            if (StringUtils.isNotBlank(paramDataStr)) {
                // 需要查询房屋的信息
                SqfwHouseholdRegistrationInfo householdInfo = sqfwHouseholdRegistrationInfoService.fetch(sqfwFamilyProperty.getHouseholdId());

                if (householdInfo != null) {
                    QuarterStatisticalTableExcelDTO.QuarterStatisticalTableExcelRowDataDTO excelDTO = new QuarterStatisticalTableExcelDTO.QuarterStatisticalTableExcelRowDataDTO();
                    FamilyPropertyParamDataDTO familyPropertyParamData = JSONObject.parseObject(paramDataStr, FamilyPropertyParamDataDTO.class);

                    BeanUtil.copyProperties(householdInfo, excelDTO);
                    BeanUtil.copyProperties(familyPropertyParamData, excelDTO);

                    // 上一年当前季度数据
                    BigDecimal lastYearNetPerIncome = BigDecimal.ZERO;
                    SqfwFamilyProperty lastYearFamilyProperty = lastYearFamilyPropertyMap.get(householdInfo.getId());
                    if (lastYearFamilyProperty != null) {
                        String lastYearParamDataStr = lastYearFamilyProperty.getParamData();
                        FamilyPropertyParamDataDTO lastYearFamilyParamData = JSONObject.parseObject(lastYearParamDataStr, FamilyPropertyParamDataDTO.class);
                        lastYearNetPerIncome = lastYearFamilyParamData.getHouseholdNetPerIncome();   // 上一年的这个季度的人均纯收入
                    }

                    // 上一年第四季度数据
                    BigDecimal lastYearFourNetPerIncome = BigDecimal.ZERO;
                    SqfwFamilyProperty lastYearFourProperty = lastYearFourQuarterPropertyMap.get(householdInfo.getId());
                    if (lastYearFamilyProperty != null) {
                        String lastYearFourParamDataStr = lastYearFourProperty.getParamData();
                        FamilyPropertyParamDataDTO lastYearFourFamilyParamData = JSONObject.parseObject(lastYearFourParamDataStr, FamilyPropertyParamDataDTO.class);
                        lastYearFourNetPerIncome = lastYearFourFamilyParamData.getHouseholdNetPerIncome();   // 上一年全年的人均纯收入
                    }

                    // 当年全年家庭人均纯收入目标
                    BigDecimal householdNetPerIncomeTarget = lastYearFourNetPerIncome.multiply(new BigDecimal("1.08")).setScale(2, RoundingMode.HALF_UP);
                    // 当年当季度家庭人均纯收入目标
                    BigDecimal curQuarterHouseHoldNetPerIncomeTarget = lastYearNetPerIncome.multiply(new BigDecimal("1.08")).setScale(2, RoundingMode.HALF_UP);


                    // 开始填充excel数据
                    excelDTO.setLastYearHouseholdNetPerIncome(lastYearFourNetPerIncome.setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setLastYearCurQuarterHouseholdNetPerIncome(lastYearNetPerIncome.setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setHouseholdNetPerIncomeTarget(householdNetPerIncomeTarget.setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setCurQuarterHouseHoldNetPerIncomeTarget(curQuarterHouseHoldNetPerIncomeTarget.setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setCurQuarterTotalHouseHoldIncome(familyPropertyParamData.getTotalHouseHoldIncome().setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setCurQuarterHouseholdNetIncome(familyPropertyParamData.getHouseholdNetIncome().setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setCurQuarterHouseholdNetPerIncome(familyPropertyParamData.getHouseholdNetPerIncome().setScale(2, RoundingMode.HALF_UP).toString());

                    BigDecimal netPerIncomeIncrease = new BigDecimal("100");
                    if (lastYearNetPerIncome.compareTo(new BigDecimal("0")) != 0) {
                        netPerIncomeIncrease = familyPropertyParamData.getHouseholdNetPerIncome().divide(lastYearNetPerIncome, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
                    }
                    excelDTO.setCurQuarterHouseholdNetPerIncomeIncrease(netPerIncomeIncrease + "%");

                    excelDTO.setPlantIndustryIncome(Optional.ofNullable(familyPropertyParamData.getPlantIndustryIncome()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setAnimalHusbandryIncome(Optional.ofNullable(familyPropertyParamData.getAnimalHusbandryIncome()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setProductionAndOperationIncome(Optional.ofNullable(familyPropertyParamData.getProductionAndOperationIncome()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setOtherSalaryIncome(Optional.ofNullable(familyPropertyParamData.getOtherSalaryIncome()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setPublicWelfarePositionIncome(Optional.ofNullable(familyPropertyParamData.getPublicWelfarePositionIncome()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setPropertyIncome(Optional.ofNullable(familyPropertyParamData.getPropertyIncome()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setMinLivAllow(Optional.ofNullable(familyPropertyParamData.getMinLivAllow()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setFamilyPlanAllowance(Optional.ofNullable(familyPropertyParamData.getFamilyPlanAllowance()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setAsstFund(Optional.ofNullable(familyPropertyParamData.getAsstFund()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setEcoComp(Optional.ofNullable(familyPropertyParamData.getEcoComp()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setPension(Optional.ofNullable(familyPropertyParamData.getPension()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setPropertyBonus(Optional.ofNullable(familyPropertyParamData.getPropertyBonus()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setWorkBonus(Optional.ofNullable(familyPropertyParamData.getWorkBonus()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setOtherTransferIncome(Optional.ofNullable(familyPropertyParamData.getOtherTransferIncome()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setPlantIndustryExpense(Optional.ofNullable(familyPropertyParamData.getPlantIndustryExpense()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setAnimalHusbandryExpense(Optional.ofNullable(familyPropertyParamData.getAnimalHusbandryExpense()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setOtherExpense(Optional.ofNullable(familyPropertyParamData.getOtherExpense()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
                    excelDTO.setSpecialReduceAndOperationExpense(Optional.ofNullable(familyPropertyParamData.getSpecialReduceAndOperationExpense()).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());

                    excelDTO.setYearDesc(year);
                    excelDTO.setQuarterDesc(StrFormatter.format("截至第{}季度末", quarterChinese(Integer.parseInt(quarter))));
                    excelDTO.setPeopleNum(sqfwFamilyProperty.getPeopleNumber());
                    excelDTO.setHouseholdBurdenPeopleNum(sqfwFamilyProperty.getPeopleNumber());

                    rowDataList.add(excelDTO);
                }
            }
        }

        result.setRowDataList(rowDataList);
        return result;
    }

    private static String quarterChinese(Integer quarter) {
        switch (quarter) {
            case (1):
                return "一";
            case (2):
                return "二";
            case (3):
                return "三";
            case (4):
                return "四";
        }
        return "";
    }

}
